package com.hdy.utils.serialize;
/*
	by 何栋宇
	2013-1-28
 */
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import net.sf.ezmorph.bean.BeanMorpher;
import net.sf.ezmorph.bean.MorphDynaBean;
import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
import net.sf.json.JsonConfig;
import net.sf.json.util.JSONUtils;

import com.caucho.burlap.io.BurlapInput;
import com.caucho.burlap.io.BurlapOutput;

public class SerializerUtil {
	private static SerializerUtil instance = new SerializerUtil();

	private SerializerUtil(){}
	
	public static SerializerUtil get(){
		return instance;
	}
	/**
	 * Recover object from string with burlap protocal
	 * @param objectCode
	 * @return
	 * @throws IOException
	 */
	public Object readBurlapObject(String objectCode) throws IOException 

{
        return readBurlapObject(objectCode, "UTF-8");
	}
	/**
	 * Write object with burlap protocal.
	 * @param object
	 * @return
	 * @throws IOException
	 */
	public String writeBurlapObject(Object object) throws IOException {
        return writeBurlapObject(object, "UTF-8");
	}
	/**
	 * Recover object from string with JSON protocal
	 * @param jsonString
	 * @return
	 * @throws IOException
	 */
	public Object readJsonObject(String jsonString, Class beanClass) {
		return readJsonObject(jsonString, beanClass, null);
//		return JSONObject.toBean(JSONObject.fromObject(objectCode), beanClass);
	}
	/**
	 * 字符串转换成任意对象 JAVA 对象，并且必须指定目标 Class 类型。
	 * 另外，
	 * 1. 如果根对象是 List ，则目标类指定 List 存放的 JAVA 类型；
	 * 2. 如果是 Map 对象，则每个 key 值必须指定JAVA对象，才能转为完整目

标 Map 对象，
	 * 如果不指定系统不报错，但Map里的每个对象则是 

net.sf.ezmorph.bean.MorphDynaBean 类型，
	 * 此时可以使用 jsonMorphToBean() 接口完成 MorphDynaBean 到 目标类型 

的转换。
	 * 3. 如果是JAVA对象，若其中属性是自定义JAVA类型，则处理与 Map 类似。
	 * @param jsonString JSON 字符串
	 * @param beanClass 对应的 JAVA 类型 Class
	 * @param classMap
	 * @return
	 */
	public Object readJsonObject(String jsonString, Class beanClass,Map<String, Class> classMap) {
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setRootClass( beanClass );
		if(classMap != null)
			jsonConfig.setClassMap( classMap );
		return JSONSerializer.toJava(JSONSerializer.toJSON(jsonString), jsonConfig);
//		return JSONObject.toBean(JSONObject.fromObject(objectCode), beanClass, classMap);
	}
	/**
	 * 将JSON字符串解析成List对象
	 * @param jsonString JSON 字符串
	 * @param pojoClz 数组中存储的pojo类对象
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<Object> readJsonList(String jsonString, Class pojoClz){
		//设定日期转换格式  
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] {"yyyy-MM-dd HH:mm:ss","yyyy-MM-dd HH:mm","yyyy-MM-dd HH","yyyy-MM-dd" }));
		  
		JSONArray jsonArray = JSONArray.fromObject(jsonString);
		JSONObject jsonObject;
		Object pojoValue;
		List<Object> list = new ArrayList<Object>();
		for (int i = 0; i < jsonArray.size(); i++) {
			jsonObject = jsonArray.getJSONObject(i);
			pojoValue = JSONObject.toBean(jsonObject, pojoClz);
			list.add(pojoValue);

		}
		return list;
	}
	@SuppressWarnings("unchecked")
	public <T> T jsonMorphToBean(MorphDynaBean morph, Class<T> toClz){
		morph.getMorpherRegistry().registerMorpher(new BeanMorpher(toClz, morph.getMorpherRegistry() ));
		return (T)morph.getMorpherRegistry().morph(toClz, morph);
	}
	/**
	 * Write object with JSON protocal.
	 * @param object
	 * @return
	 * @throws IOException
	 */
	public String writeJsonObject(Object object) {
		
		return JSONSerializer.toJSON(object).toString();
	}
	

	private Object readBurlapObject(String objectCode, String enc) throws IOException {
		InputStream is = null;
		try {
			is = new ByteArrayInputStream(objectCode.getBytes(enc));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
        BurlapInput in = new BurlapInput(is);
        return in.readObject();
	}
	private String writeBurlapObject(Object object, String enc) throws IOException {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		BurlapOutput bOut = new BurlapOutput(out);
		bOut.writeObject(object);
        return out.toString(enc);
	}
}

